/*
 *
 */

package programs;

import columnar.Columnarfile;
import global.AttrType;
import global.TID;
import heap.FieldNumberOutOfBoundException;
import heap.InvalidSlotNumberException;
import heap.InvalidTupleSizeException;
import heap.Tuple;
import java.io.*;

import diskmgr.PCounter;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author SHIVANI
 * Modified by Tim 03/25/2011
 * Modified by Tim 03/26/2011
 * Modified by Tim 04/01/2011
 */
public class BatchInsert
{
    public static int MAX_ARR_LEN = 5000;
    private static short REC_LEN_STRING = 160;
    private static short REC_LEN_INT = 32;

    public static String dataFileName;
    public static String columnDBName;
    public static String columnarFileName;
    public static int numColumns;
    public static AttrType [] typeArr;
   // public static List columnarTidsArr;
    public static Columnarfile cf = null;
    
    public static void main (String [] argv) throws Exception
    {
      //  argv[0] ="F:/asu/DBMS-I/Project/SVN Project Repo/src/datafile";
        if(argv.length != 4){
            System.out.println("The command line invocation must be as follows: \n\t"
                    + "batchInsert DATAFLILENAME COLUMNDBNAME COLUMNARFILENAME NUMCOLUMNS");
            Runtime.getRuntime().exit(1);
       }


        dataFileName = argv[0];
        columnDBName = argv[1];
        columnarFileName = argv[2];
        numColumns = Integer.parseInt(argv[3]);
        typeArr =  new AttrType[numColumns];
        //columnarTidsArr = new LinkedList();
        short[] attrSize = new short[numColumns];
        
        System.out.println ("\n" + "Running Batch Insert test...." + "\n");

        global.SystemDefs sysdef = new global.SystemDefs(columnDBName,0,300,"Clock");

        //Read DataFile
        File file = new File(dataFileName);
        FileInputStream fis     = null;
        BufferedInputStream bis = null;
        DataInputStream dis     = null;

        try {
            fis = new FileInputStream(file);

            // Here BufferedInputStream is added for fast reading.
            bis = new BufferedInputStream(fis);
            dis = new DataInputStream(bis);
            
            /***Get the Column names and the AttrType from the first line.***/
            //read the file line by line
            String str = dis.readLine();

            int count = 1;
            String [] columnNames = new String[numColumns];  //Array to store the column names.
            int collen = 0;

            for(String s : str.split("\\t"))
            {
                count=1;
                for(String st : s.split(":"))
                {
                    if(count %2 !=0)
                    {
                       columnNames[collen]=st;
                       count++;
                    }
                    else
                    {
                        if(st.contains("char"))
                        {
                            typeArr[collen] = new AttrType (AttrType.attrString);
                            attrSize[collen] = REC_LEN_STRING;
                        }
                        else if(st.equals("int"))
                        {
                            typeArr[collen] = new AttrType (AttrType.attrInteger);
                            attrSize[collen] =  REC_LEN_INT;
                        }
                    }
                    
                }
                collen++;
            } 
            //end of the first line of the Datafile and output: Array's- columnNames, typeArr

            //Create ColumnarFile
            try{
                cf = new Columnarfile(columnarFileName, numColumns, typeArr,columnNames);
            }catch(Exception e){
                System.out.println("Cannot create CF");
                e.printStackTrace();
            }


            //Create Tuples to store in the columnar file..

            int lineCount = 0;
            
           // Integer numColumnsVal = new Integer(numColumns);
            while (dis.available() != 0)
            {
                String astr = dis.readLine();
                count = 1;

                // create a tuple of appropriate size
                Tuple t = new Tuple();
                try {
                  t.setHdr((short)numColumns, typeArr, attrSize);
                }
                catch (Exception e) {
                  e.printStackTrace();
                }
                int columnCount = 0;
                for(String s : astr.split("\\t"))
                {
                    if(s.contains(":"))
                        break;
                    else if(!s.trim().equals(""))
                    {
                        if(typeArr[columnCount].attrType == AttrType.attrString)
                            t.setStrFld(columnCount+1, s.trim());
                        else if (typeArr[columnCount].attrType == AttrType.attrInteger)
                        {
                            int intVal = Integer.valueOf(s.trim());
                            t.setIntFld(columnCount+1, intVal);
                        }
                        columnCount++;
                    }
                    
                }
                TID tid = new TID(numColumns);
                tid = cf.insertTuple(t);
                System.out.print(".");
                if(lineCount%100 == 100)
                	System.out.print(".");
                if(lineCount%1000 == 0)
                	System.out.print("\n"+lineCount);
                //columnarTidsArr.add(tid);//[lineCount] = tid;
                lineCount++;
            }

            // dispose all the resources after using them.
            fis.close();
            bis.close();
            dis.close();
            System.out.print("\n");  

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        
        sysdef.JavabaseBM.flushAllPages();

        System.out.println("Tuple Count: "+cf.getTupleCnt());
        PCounter.print();
        Runtime.getRuntime().exit(0);

    }
}
